package com.github.gdxmap.geometry;

import com.badlogic.gdx.math.GridPoint2;

import java.io.Serializable;

/**
 * Created by free on 2016/12/6 0006.
 */
public class Point implements Serializable{
    public float x;
    public float y;

    /** Constructs a new 2D grid point. */
    public Point () {
    }

    /** Constructs a new 2D grid point.
     *
     * @param x X coordinate
     * @param y Y coordinate */
    public Point (float x, float y) {
        this.x = x;
        this.y = y;
    }

    /** Copy constructor
     *
     * @param point The 2D grid point to make a copy of. */
    public Point (Point point) {
        this.x = point.x;
        this.y = point.y;
    }

    /** Sets the coordinates of this 2D grid point to that of another.
     *
     * @param point The 2D grid point to copy the coordinates of.
     *
     * @return this 2D grid point for chaining. */
    public Point set (Point point) {
        this.x = point.x;
        this.y = point.y;
        return this;
    }

    /** Sets the coordinates of this 2D grid point.
     *
     * @param x X coordinate
     * @param y Y coordinate
     *
     * @return this 2D grid point for chaining. */
    public Point set (int x, int y) {
        this.x = x;
        this.y = y;
        return this;
    }

    /**
     * @param other The other point
     * @return the squared distance between this point and the other point.
     */
    public float dst2 (Point other) {
        float xd = other.x - x;
        float yd = other.y - y;

        return xd * xd + yd * yd;
    }

    /**
     * @param x The x-coordinate of the other point
     * @param y The y-coordinate of the other point
     * @return the squared distance between this point and the other point.
     */
    public float dst2 (float x, float y) {
        float xd = x - this.x;
        float yd = y - this.y;

        return xd * xd + yd * yd;
    }

    /**
     * @param other The other point
     * @return the distance between this point and the other vector.
     */
    public float dst (Point other) {
        float xd = other.x - x;
        float yd = other.y - y;

        return (float)Math.sqrt(xd * xd + yd * yd);
    }

    /**
     * @param x The x-coordinate of the other point
     * @param y The y-coordinate of the other point
     * @return the distance between this point and the other point.
     */
    public float dst (float x, float y) {
        float xd = x - this.x;
        float yd = y - this.y;

        return (float)Math.sqrt(xd * xd + yd * yd);
    }

    /**
     * Adds another 2D grid point to this point.
     *
     * @param other The other point
     * @return this 2d grid point for chaining.
     */
    public Point add (Point other) {
        x += other.x;
        y += other.y;
        return this;
    }

    /**
     * Adds another 2D grid point to this point.
     *
     * @param x The x-coordinate of the other point
     * @param y The y-coordinate of the other point
     * @return this 2d grid point for chaining.
     */
    public Point add (int x, int y) {
        this.x += x;
        this.y += y;
        return this;
    }

    /**
     * Subtracts another 2D grid point from this point.
     *
     * @param other The other point
     * @return this 2d grid point for chaining.
     */
    public Point sub (Point other) {
        x -= other.x;
        y -= other.y;
        return this;
    }

    /**
     * Subtracts another 2D grid point from this point.
     *
     * @param x The x-coordinate of the other point
     * @param y The y-coordinate of the other point
     * @return this 2d grid point for chaining.
     */
    public Point sub (int x, int y) {
        this.x -= x;
        this.y -= y;
        return this;
    }

    /**
     * @return a copy of this grid point
     */
    public Point cpy () {
        return new Point(this);
    }

    @Override
    public boolean equals (Object o) {
        if (this == o) return true;
        if (o == null || o.getClass() != this.getClass()) return false;
        Point g = (Point)o;
        return this.x == g.x && this.y == g.y;
    }

    @Override
    public int hashCode () {
        final int prime = 53;
        int result = 1;
        result = (int)(prime * result + this.x);
        result = (int)(prime * result + this.y);
        return result;
    }

    @Override
    public String toString () {
        return "(" + x + ", " + y + ")";
    }

    public float[] toArray(){
        return new float[]{x,y};
    }
}
